package cfengMiddleware.server.rabbitmq.consumer;

import cfengMiddleware.server.rabbitmq.entity.MessageEntity;
import cfengMiddleware.server.rabbitmq.entity.Student;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.Channel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;

/**
 * @author Cfeng
 * @date 2022/9/15
 * rabbitMQ基础模型 消费者，监听接收消息
 */

@Component
@Slf4j
@RequiredArgsConstructor
public class BasicConsumer implements ChannelAwareMessageListener {

    private final ObjectMapper objectMapper;

    /**
     * @param message
     * @param channel 通道实例
     * @throws Exception
     */
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        //这里就是rabbit的一个Message监听器，可以监听到消息
        MessageProperties properties = message.getMessageProperties();
        //获取消息分发的全局标识
        long deliveryTag = properties.getDeliveryTag();
        try {
            byte[] msg = message.getBody();
            //解析消息
            String entity = objectMapper.readValue(msg,String.class);
            //log
            log.info("确认消费模式 - 人为手动确认消息： {}", entity);
            //执行业务逻辑后，手动ACK， deliverTag 为全局分发标识（唯一）  是否允许批量消费: 这里设置为true
            channel.basicAck(deliveryTag,true);
        } catch (Exception e) {
            log.info("人为手动确认消费- 监听到消息： {}", e.fillInStackTrace());
            //发生异常，拒绝ACK
            channel.basicReject(deliveryTag,false);
        }
    }

    /**
     *  监听接收消费队列中的消息， 这里采用单一容器工厂
     * @param msg  传输的二进制消息，这里的@PayLoad和之前的STOMP的是类似的就是将消息转化为给定的类型
     *  这里使用@RabbitListener 类似之前STOMP的@MessageMapping类似
     */
//    @RabbitListener(queues = "${spring.rabbitmq.queue-name}",containerFactory = "singleListenerContainer")
//    public void consumeMsg(@Payload byte[] msg) {
//        try {
//            String message = new String(msg, StandardCharsets.UTF_8);
//            log.info("基本消费模型 消费者：监听到消息： {}", message);
//        } catch (Exception e) {
//            log.error("基本消息模型-消费者 发生异常 ： {}",e.fillInStackTrace());
//        }
//    }
//
//    @RabbitListener(queues = "${spring.rabbitmq.queue-object-name}",containerFactory = "singleListenerContainer")
//    public void consumeObjMsg(@Payload Student student) {
//        try {
//            log.info("基本消费模型 --- 消费者： 监听到消息: {}",student);
//        } catch (Exception e) {
//            log.error("基本消费模型 --- 消费者： 监听消息异常 {}", e.fillInStackTrace());
//        }
//    }
}
